package com.yeyks.commonReference.append.mattress.wechat.service;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.yeyks.common.em.mattress.MattressPayRecordStatusEnum;
import com.yeyks.common.em.mattress.OrderInfoMattressOrderTypeEnum;
import com.yeyks.common.em.mattress.OrderInfoMattressPayTypeEnum;
import com.yeyks.common.em.mattress.OrderInfoMattressStatusEnum;
import com.yeyks.common.em.pay.PayTypeEnum;
import com.yeyks.common.exception.ServiceException;
import com.yeyks.commonReference.append.mattress.wechat.config.MattressWxProperties;
import com.yeyks.commonReference.append.mattress.wechat.param.MattressWechatPayServiceGenerateWeChatOrdersParam;
import com.yeyks.commonReference.append.mattress.wechat.param.MattressWechatPayServiceRefundParam;
import com.yeyks.commonReference.service.mattress.MattressApiService;
import com.yeyks.commonReference.service.mattress.OrderInfoMattressService;
import com.yeyks.mattress.dal.domain.MattressPayRecord;
import com.yeyks.mattress.dal.domain.OrderInfoMattress;
import com.yeyks.mattress.param.PayControllerCreateMattressPayOrderParam;
import com.yeyks.mattress.service.MattressPayRecordService;
import com.yeyks.mattress.vo.OrderInfoMattressMattressStatusVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
@ConditionalOnBean({MattressWxProperties.class})
public class MattressPayService {

    @Autowired
    private MattressWxProperties mattressWxProperties;
    @Autowired
    private MattressWechatPayService mattressWechatPayService;
    @Autowired
    private OrderInfoMattressService orderInfoMattressService;
    @Autowired
    private MattressPayRecordService mattressPayRecordService;
    @Autowired
    private MattressApiService mattressApiService;

    //床垫订单支付
    public Map<String, Object> createMattressPayOrder(PayControllerCreateMattressPayOrderParam param) {
        //查询订单
        OrderInfoMattress orderInfoMattress = orderInfoMattressService.getOne(new QueryWrapper<OrderInfoMattress>().eq(OrderInfoMattress.ORDER_NO, param.getOrderNo()));
        if (null == orderInfoMattress) {
            throw new ServiceException("订单不存在");
        }
        if (!OrderInfoMattressStatusEnum.PRE_PAY.value().equals(orderInfoMattress.getStatus())) {
            throw new ServiceException("订单状态不正确");
        }
        //获取床垫状态
        OrderInfoMattressMattressStatusVo orderInfoMattressMattressStatusVo = mattressApiService.mattressStatusOnCheck(orderInfoMattress.getImeiId());
        if (orderInfoMattressMattressStatusVo.getStatus().equals(1)) {
            throw new ServiceException("床垫正在运行");
        }
        //生成支付记录
        MattressPayRecord mattressPayRecord = mattressPayRecordService.getOne(new QueryWrapper<MattressPayRecord>()
                .eq(MattressPayRecord.ORDER_NO, param.getOrderNo()).eq(MattressPayRecord.PAY_TYPE, OrderInfoMattressPayTypeEnum.getValue(param.getPayType())));
        if (null == mattressPayRecord) {
            Date date = new Date();
            mattressPayRecord = new MattressPayRecord();
            mattressPayRecord.setOrderNo(param.getOrderNo());
            mattressPayRecord.setStatus(MattressPayRecordStatusEnum.PAY_BEFORE.value());
            mattressPayRecord.setPayType(OrderInfoMattressPayTypeEnum.getValue(param.getPayType()));
            mattressPayRecord.setStartTime(date);
            mattressPayRecord.setPayAmount(orderInfoMattress.getSnapshotTotalFee());
            mattressPayRecord.setCreateTime(date);
            mattressPayRecord.setUpdateTime(date);
            mattressPayRecordService.save(mattressPayRecord);
        }
        //支付订单对象
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("orderNo", param.getOrderNo());
        //生成支付订单
        doPay(resultMap, OrderInfoMattressOrderTypeEnum.MATTRESS.desc(), param.getPayType(), param.getOrderNo(), orderInfoMattress.getSnapshotTotalFee(), param.getWxOpenId(), param.getIp());
        return resultMap;
    }

    /**
     * 支付统一调用的方法
     *
     * @param resultMap     用于返回的map对象
     * @param orderType     订单类型: mattress
     * @param payType       支付类型: gzh
     * @param orderNo       订单号
     * @param paymentAmount 支付金额
     * @param wxOpenId      微信openid
     * @param ip            用户ip
     * @return
     */
    public boolean doPay(Map<String, Object> resultMap, String orderType, String payType, String orderNo, Integer paymentAmount, String wxOpenId, String ip) {
        HashMap<String, String> attachMap = new HashMap<>();
        //订单类型
        attachMap.put("orderType", orderType);
        //支付类型
        attachMap.put("payType", payType);
        if (PayTypeEnum.GZH.desc().equals(payType)) {
            //更改订单号生成公众号独立订单
            orderNo += payType;
            //生成参数
            MattressWechatPayServiceGenerateWeChatOrdersParam param = new MattressWechatPayServiceGenerateWeChatOrdersParam();
            param.setPayType(payType);
            param.setOpenId(wxOpenId);
            param.setTotalFee(paymentAmount);
            param.setOrderNo(orderNo);
            param.setCreateIp(ip);
            param.setNotifyUrl(mattressWxProperties.getNewNotifyUrl());
            param.setTradeType("JSAPI");
            param.setAttach(JSONUtil.toJsonStr(attachMap));
            Map<String, Object> unifiedOrder = mattressWechatPayService.generateWeChatOrders(param);
            resultMap.put("payInfo", unifiedOrder);
            return true;
        }
        return false;
    }

    //统一退款
    public WxPayRefundResult doRefund(MattressWechatPayServiceRefundParam param) {
        String orderNo = param.getOrderNo();
        if (PayTypeEnum.GZH.desc().equals(param.getPayType())) {
            //更改订单号生成公众号独立订单
            orderNo += param.getPayType();
            param.setOrderNo(orderNo);
            return mattressWechatPayService.refund(param);
        }
        return null;
    }


    /**
     * 订单退款
     *
     * @param wxRefundParam
     * @return boolean
     */
    public Boolean disPoseRefund(MattressWechatPayServiceRefundParam wxRefundParam) {
        try {
            WxPayRefundResult refund = doRefund(wxRefundParam);
            if (refund == null) {
                log.error("订单退款返回数据为空");
                return false;
            }
            if (refund.getResultCode().equals("SUCCESS")
                    && refund.getRefundFee().equals(wxRefundParam.getRefundFee())) {
                return true;
            } else {
                log.error("订单退款失败{}", JSONObject.toJSONString(refund));
                return false;
            }
        } catch (Exception e) {
            log.error("订单退款异常{}", e.getLocalizedMessage());
            return false;
        }
    }

}
